package com.pzhu.file;

import com.pzhu.acargid.until.Result;
import com.pzhu.file.utils.FileUtil;
import com.pzhu.security.token.JwtTokenService;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

@RestController
@RequestMapping("/file")
public class FileController {
    private final Map<String, FileCount> fileCaches = new HashMap<>();
    private final Map<String, List<PdfImage>> pdfImagesCache = new HashMap<>();
    private static final String savePath = System.getProperty("user.dir") + "/file/caches/";

    /**
     * 经过测试,dpi为96,100,105,120,150,200中,105显示效果较为清晰,体积稳定,dpi越高图片体积越大,一般电脑显示分辨率为96
     */
    public static final Integer DEFAULT_DPI = 100;

    /**
     * 默认转换的图片格式为png
     */
    public static final String DEFAULT_FORMAT = "png";

    public static void savePDF(String filename, String pdfPath, List<String> images) throws IOException {
        // 创建PDF文档对象
        PDDocument document = new PDDocument();
        for (int i = 0; i < images.size(); i++) {
            // 加载图片文件
            PDImageXObject imageObj = PDImageXObject.createFromFile(savePath + images.get(i), document);
            // 创建一个页面并添加图片
            PDPage page = new PDPage(new PDRectangle(imageObj.getWidth(), imageObj.getHeight()));
            try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
                contentStream.drawImage(imageObj, 0, 0);
            }
            // 将页面添加到PDF文档
            document.addPage(page);
        }
        // 保存PDF文档
        document.save(pdfPath);
        document.close();
        System.out.println("图片成功转换为PDF文件！");
    }


    @PostMapping
    public Result upload(@RequestBody MultipartFile multipartFile) throws IOException {
        String uuid = null;
        if (multipartFile != null) {
            String Type = multipartFile.getContentType();
            String filename = UUID.randomUUID() + multipartFile.getOriginalFilename();
            if (uuid == null) {
                uuid = UUID.randomUUID().toString();
                fileCaches.put(uuid, new FileCount(0, new ArrayList<String>() {{
                    add(filename);
                }}));
            }
            FileCount fileCount = fileCaches.get(uuid);
            List<String> files = fileCount.getFiles();
            if (Type != null && Type.equals("png")) {
                files.add(filename);
                UUID imageuuid = UUID.randomUUID();
                String imagename = imageuuid + ".png";
                IOUtils.copy(multipartFile.getInputStream(), Files.newOutputStream(Paths.get(savePath + imagename)));
                pdfImagesCache.put(filename, new ArrayList<PdfImage>() {{
                    add(new PdfImage(fileCount.getCount() + 1, imagename));
                }});
                return Result.success(new FileImages(uuid, pdfImagesCache.get(filename)));
            } else {
                PDDocument document = Loader.loadPDF(multipartFile.getBytes());
                List<PdfImage> list = new ArrayList<>();
                // 创建PDF渲染器
                PDFRenderer pdfRenderer = new PDFRenderer(document);
                // 循环处理每个页面
                for (int pageNumber = 0; pageNumber < document.getNumberOfPages(); pageNumber++) {
                    // 渲染PDF页面为BufferedImage
                    BufferedImage image = pdfRenderer.renderImageWithDPI(pageNumber, DEFAULT_DPI);
                    // 保存图像为文件
                    UUID imageuuid = UUID.randomUUID();
                    String imagename = imageuuid + ".png";
                    File file = new File(savePath + imagename);
                    if (!file.exists() && !file.mkdirs()) {
                        System.err.println("创建文件夹失败，请检查目录权限！" + savePath);
                    }
                    ImageIO.write(image, "PNG", file);
                    list.add(new PdfImage(pageNumber, imagename));
                }
                // 关闭PDF文档
                document.close();
                pdfImagesCache.put(filename, list);
                return Result.success(new FileImages(uuid, list));
            }
        } else {
            return null;
        }
    }

    @GetMapping
    public Result get(HttpServletRequest request, String id, String type, String title) throws IOException {
        String uuid = null;
        Integer userid = JwtTokenService.getClaim(request, "userid").asInt();
        String pdfsavePath = FileUtil.getSavePath(userid, type) + id + File.separator + title + ".pdf";

        File inputStream = new File(pdfsavePath);
        PDDocument document = Loader.loadPDF(FileUtils.readFileToByteArray(inputStream));
        List<PdfImage> list = new ArrayList<>();
        // 创建PDF渲染器
        PDFRenderer pdfRenderer = new PDFRenderer(document);
        // 循环处理每个页面
        for (int pageNumber = 0; pageNumber < document.getNumberOfPages(); pageNumber++) {
            // 渲染PDF页面为BufferedImage
            BufferedImage image = pdfRenderer.renderImageWithDPI(pageNumber, DEFAULT_DPI);
            // 保存图像为文件
            UUID imageuuid = UUID.randomUUID();
            String imagename = imageuuid + ".png";
            File file = new File(savePath + imagename);
            if (!file.exists() && !file.mkdirs()) {
                System.err.println("创建文件夹失败，请检查目录权限！" + savePath);
            }
            ImageIO.write(image, "PNG", file);
            list.add(new PdfImage(pageNumber, imagename));
        }
        // 关闭PDF文档
        document.close();
        return Result.success(new FileImages(uuid, list));
    }
}
